// HidISPDlg.cpp : implementation file
//

#include "stdafx.h"
#include "HidISP.h"
#include "HidISPDlg.h"
#include "Register.h"
#include "AppInvoker.h"

#pragma comment(lib, "..\\HIDLoader\\HIDLoader.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CHidISPDlg dialog




CHidISPDlg::CHidISPDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CHidISPDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHidISPDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_PROGRESS1, m_progress);
    DDX_Control(pDX, IDC_TREE1, m_regCfg);
    DDX_Control(pDX, IDC_COMBO1, m_log);
}

BEGIN_MESSAGE_MAP(CHidISPDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_LOAD_FILE, &CHidISPDlg::OnBnClickedLoadFile)
    ON_BN_CLICKED(IDC_UPDATE, &CHidISPDlg::OnBnClickedUpdate)
    ON_BN_CLICKED(IDC_UPDATE_CONFIG, &CHidISPDlg::OnBnClickedUpdateConfig)
    ON_BN_CLICKED(IDC_READ_CONFIG, &CHidISPDlg::OnBnClickedReadConfig)
    ON_BN_CLICKED(IDC_RESET2APROM, &CHidISPDlg::OnBnClickedReset2aprom)
    ON_BN_CLICKED(IDC_RESET2LDROM, &CHidISPDlg::OnBnClickedReset2ldrom)
    ON_BN_CLICKED(IDC_GEN_FIRMWARE, &CHidISPDlg::OnBnClickedGenFirmware)
END_MESSAGE_MAP()


// CHidISPDlg message handlers

BOOL CHidISPDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
    
    m_regCfg.LoadXML("regcfg.xml");

    if(Open(0x0250,0x0250,GetSafeHwnd()) == ERROR_SUCCESS)
    {
        TitleConnect();
    }else{
       // AfxMessageBox(_T("Can not find ISP device!"));
        TitleDisconnect();
    }

    GetDlgItem(IDC_UPDATE)->EnableWindow(FALSE);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CHidISPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CHidISPDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CHidISPDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CHidISPDlg::OnBnClickedLoadFile()
{
    TCHAR szFilters[]=
   _T("Hex Files (*.hex)|*.hex|All Files (*.*)|*.*||");
   CFileDialog	fileDlg(true,_T("*"),_T("*.bin"),OFN_FILEMUSTEXIST| OFN_HIDEREADONLY|OFN_EXPLORER  ,szFilters,0,0);
   if( fileDlg.DoModal ()==IDOK ){
       if(LoadFile(fileDlg.GetPathName())){
           GetDlgItem(IDC_UPDATE)->EnableWindow(TRUE);
       }else{
           GetDlgItem(IDC_UPDATE)->EnableWindow(FALSE);
       }
   }
}

void CHidISPDlg::OnBnClickedUpdate()
{
    ProgDevice(this);
}

void CHidISPDlg::OnOK()
{
}

void CHidISPDlg::OnBnClickedUpdateConfig()
{
    ConfigProg_t cfg = {0};
    cfg.config0 = m_regCfg.GetValue(CFG0_ADDR); 
    cfg.config1 = m_regCfg.GetValue(CFG1_ADDR);
    cfg.bRead = 0;
    this->EnterConfigMode();
    WriteAndWait(&cfg);
    //m_regCfg.SetValue(0x300000,-1);
    //m_regCfg.Update();
}

void CHidISPDlg::OnBnClickedReadConfig()
{
    //m_regCfg.SetValue(0x300000,0x06000000);
    //m_regCfg.Update();

    BeginReadData();
    this->EnterConfigMode();
    ConfigProg_t cfg;
    cfg.bRead = 1;
    WriteAndWait(&cfg);
}

void CHidISPDlg::OnReadData(BYTE* pData, size_t dataLen)
{
    PConfigProg_t p = (PConfigProg_t)pData;
    m_regCfg.SetValue(CFG0_ADDR,p->config0);
    m_regCfg.SetValue(CFG1_ADDR,p->config1);
    m_regCfg.Update();
}

void	CHidISPDlg::OnConnect(LPCTSTR path)
{
    //if(CString(path).CompareNoCase(m_devicePath) == 0)
    {
        if(Open(path) == ERROR_SUCCESS){
            TitleConnect();
        }
    }
}
void	CHidISPDlg::OnDisconnect(LPCTSTR path)
{
    if(CString(path).CompareNoCase(GetDevPath()) == 0){
        Close();
        TitleDisconnect();
    }
}

LRESULT CHidISPDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if(message == WM_DEVICECHANGE){
        return CHIDLoader::OnDeviceChange(wParam,lParam);
    }else if(message == WM_LOADER){
        switch(wParam){
            case WML_UPDATE_STATUS:
                m_log.AddString(LPCTSTR(lParam));
                m_log.SetWindowText(LPCTSTR(lParam));
                break;
        }
    }
	return CDialog::WindowProc(message,wParam,lParam);
}

void CHidISPDlg::OnBnClickedReset2aprom()
{
    if(IsBootloaderRunning()){
        Reset2APROM();
    }
}

void CHidISPDlg::OnBnClickedReset2ldrom()
{
    if(IsBootloaderRunning() == FALSE){
        Reset2LDROM();
    }
}

void CHidISPDlg::OnBnClickedGenFirmware()
{
    CAppInvoker ivk;
    ivk.Invoke(_T("C:\\dev\\CanAnalyzer\\CPP\\debug\\ispcrypt.exe"),_T(""),false,true,false);
}

void CHidISPDlg::TitleConnect()
{
    OnBnClickedReadConfig();
    if(IsBootloaderRunning()){
        SetWindowText(_T("Hid Isp - Connect (Bootloader)"));
    }else{
        SetWindowText(_T("Hid Isp - Connect (Application)"));
    }
    if(IsBootloaderRunning()){
        GetDlgItem(IDC_RESET2APROM)->EnableWindow(TRUE);
        GetDlgItem(IDC_RESET2LDROM)->EnableWindow(FALSE);
    }else{
        GetDlgItem(IDC_RESET2APROM)->EnableWindow(FALSE);
        GetDlgItem(IDC_RESET2LDROM)->EnableWindow(TRUE);
    }
}

void CHidISPDlg::TitleDisconnect()
{
    if(IsBootloaderRunning()){
        SetWindowText(_T("Hid Isp - Disconnect"));
    }else{
        SetWindowText(_T("Hid Isp - Disconnect"));
    }
}

void CHidISPDlg::OnStartProg()
{
    GetDlgItem(IDC_UPDATE)->EnableWindow(FALSE);
    GetDlgItem(IDC_READ_CONFIG)->EnableWindow(FALSE);
    GetDlgItem(IDC_UPDATE_CONFIG)->EnableWindow(FALSE);
    GetDlgItem(IDC_RESET2LDROM)->EnableWindow(FALSE);
    GetDlgItem(IDC_RESET2APROM)->EnableWindow(FALSE);
}

void CHidISPDlg::OnStopProg()
{
    GetDlgItem(IDC_UPDATE)->EnableWindow(TRUE);
    GetDlgItem(IDC_READ_CONFIG)->EnableWindow(TRUE);
    GetDlgItem(IDC_UPDATE_CONFIG)->EnableWindow(TRUE);
    if(IsBootloaderRunning()){
        GetDlgItem(IDC_RESET2APROM)->EnableWindow(TRUE);
        GetDlgItem(IDC_RESET2LDROM)->EnableWindow(FALSE);
    }else{
        GetDlgItem(IDC_RESET2APROM)->EnableWindow(FALSE);
        GetDlgItem(IDC_RESET2LDROM)->EnableWindow(TRUE);
    }
}

BYTE CHidISPDlg::IsBootloaderRunning()
{
    BYTE res = 0;
    wchar_t ch[128];
    BOOLEAN r = GetSerialString(ch,128);
    if( (ch[0] == L'L') && (ch[1] == L'D') ){
        res = 1;
    }
	return res;
}

void CHidISPDlg::EnterConfigMode()
{
	GetIndexedString(CONFIG_PROG);
}

void CHidISPDlg::Reset2LDROM()
{
	GetIndexedString(RESET2LDROM);
    BYTE x[128] = {0};
    WriteAndWait(x);
}

void CHidISPDlg::Reset2APROM()
{
	GetIndexedString(RESET2APROM);
    BYTE x[128] = {0};
    WriteAndWait(x);
}

void CHidISPDlg::SetRange(int start, int end)
{
    m_progress.SetRange(start,end);
}

void CHidISPDlg::SetPos(int pos)
{
    m_progress.SetPos(pos);
}

